﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace CKS.EBE.Logging
{
	public class Logger
	{
		private static object _lock = new object();
		private readonly LoggingLevel _level;
		private List<LogEntry> Logentries { get; set; }

		/// <summary>
		/// 
		/// </summary>
		/// <param name="level">define which logentries will be written to the logfile</param>
		public Logger(LoggingLevel level)
		{
			_level = level;
			Logentries = new List<LogEntry>();
		}

		/// <summary>
		/// add Verbose entry to Logger and write a Trace
		/// </summary>
		/// <param name="method"></param>
		/// <param name="message"></param>
		public void Verbose(string method, string message)
		{
			Logentries.Add(new LogEntry(method, message, LoggingLevel.Verbose));
			Trace.WriteLine(string.Format("{0}\t{1}", method, message));
		}

		/// <summary>
		/// add Information entry to Logger and write a Trace
		/// </summary>
		/// <param name="method"></param>
		/// <param name="message"></param>
		public void Information(string method, string message)
		{
			Logentries.Add(new LogEntry(method, message, LoggingLevel.Information));
			Trace.WriteLine(string.Format("{0}\t{1}", method, message));
		}

		/// <summary>
		/// add Warning entry to Logger and write a Trace
		/// </summary>
		/// <param name="method"></param>
		/// <param name="message"></param>
		public void Warning(string method, string message)
		{
			Logentries.Add(new LogEntry(method, message, LoggingLevel.Warning));
			Trace.WriteLine(string.Format("{0}\t{1}", method, message));
		}

		/// <summary>
		/// add Error entry to Logger and write a Trace
		/// </summary>
		/// <param name="method"></param>
		/// <param name="message"></param>
		public void Error(string method, string message)
		{
			Logentries.Add(new LogEntry(method, message, LoggingLevel.Error));
			Trace.WriteLine(string.Format("{0}\t{1}", method, message));
		}

		/// <summary>
		/// add an Exception entry to the ULS Log and write a Trace
		/// </summary>
		/// <param name="ex"></param>
		/// <param name="method"></param>
		public static void Error(Exception ex, string method)
		{
			Trace.WriteLine(method + " " + ex);
			if (SPContext.Current.Web == null) return;

			var blogSettings = new BlogSettings(SPContext.Current.Web);
			var level = (LoggingLevel)blogSettings.LoggingLevel;
			var logger = new Logger(level);
			logger.Error(method, ex.ToString());
		}

		/// <summary>
		/// store trackback log in the LOG path beneath the 12 hive in a file 'TrackbackLog.txt'
		/// </summary>
		/// <param name="logFileName">e.g. "TrackbackLog.txt"</param>
		public void WriteEntriesToLog(string logFileName)
		{
			try
			{
				if (_level == LoggingLevel.None) return;

				lock (_lock)
				{
					string logPath = SPUtility.GetGenericSetupPath("LOGS");
					string logfile = Path.Combine(logPath, logFileName);
					using (var writer = new StreamWriter(logfile, true))
					{
						bool addEndLine = false;
						foreach (LogEntry logEntry in Logentries)
						{
							if (logEntry.Level >= _level)
							{
								addEndLine = true;
								writer.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", logEntry.Time, logEntry.Level, logEntry.Method, logEntry.Message));
							}
						}
						if (addEndLine)
						{
							writer.WriteLine("------------------------------------------------------------------------");
						}
					}
				}
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex);
			}
		}
	}
}
